﻿using System;
using System.Windows;
using System.Windows.Controls;

using Hetymine.Executioner.Commands;

namespace Hetymine.Executioner.Controls {
    /// <summary>
    /// Interaction logic for HotStringCommand.xaml
    /// </summary>
    public partial class HotStringCommand : UserControl, ICommandConfigurator<ICommand> {
        private bool _IsApply = false;
        private HotString _HotString;

        public HotStringCommand() {
            InitializeComponent();


            this.hsHotString.TextChanged += new TextChangedEventHandler(hsHotString_TextChanged);
            this.hsAudioInput.Click += new RoutedEventHandler(hsAudioInput_Click);
            this.hsCommand.CommandChanged += new EventHandler(hsCommand_CommandChanged);
            this.hsAddCommand.Click += new RoutedEventHandler(hsAddCommand_Click);
            this.hsRemoveCommand.Click += new RoutedEventHandler(hsRemoveCommand_Click);
        }

        private string CommandName {
            get {
                if (this._HotString.IsEmpty) {
                    return string.Empty;
                }
                
                return this._HotString.ToString();
            }
        }

        private void hsHotString_TextChanged(object sender, TextChangedEventArgs e) {
            if (!this._IsApply || this._HotString == null) { return; }
            
            this._HotString.Name = this.hsHotString.Text.Trim();

            this.OnCommandNameChanged(this, new CommandNameEventArgs(this.CommandName));
        }        
        private void hsAudioInput_Click(object sender, RoutedEventArgs e) {
            if (!this._IsApply || this._HotString == null) { return; }

            if (this.hsAudioInput.IsChecked == true) {
                this._HotString.DisableInput("string");
                this._HotString.EnableInput("audio");
            }
            else if (this.hsAudioInput.IsChecked == null) {
                this._HotString.EnableInput("audio");
                this._HotString.EnableInput("string");
            }
            else {
                this._HotString.DisableInput("audio");
                this._HotString.EnableInput("string");
            }

            this.OnCommandNameChanged(this, new CommandNameEventArgs(this.CommandName));
        }
        private void hsCommand_CommandChanged(object sender, EventArgs e) {
            if (!this._IsApply || this._HotString == null) { return; }

            CommandSelector cs = sender as CommandSelector;

            CommandInfo ci = new CommandInfo(
                cs.Command,
                cs.Arguments
            );

            if (this._HotString.Commands.Count == 0) {
                this._HotString.Commands.Add(ci);
            }
            else {
                int tabIndex = this.hsTabCommands.SelectedIndex;
                this._HotString.Commands[tabIndex] = ci;
            }

            this.OnCommandNameChanged(this, new CommandNameEventArgs(this.CommandName));
        }
        
        private void hsAddCommand_Click(object sender, RoutedEventArgs e) {            
            if (this._HotString == null || this.hsTabCommands.Items.Count == 8) { return; }

            // Since there is always at least one tab, ensure at least one command
            // info exists before adding another.
            if (this._HotString.Commands.Count == 0) {
                this._HotString.Commands.Add(new CommandInfo());
            }
            this._HotString.Commands.Add(new CommandInfo());

            TabItem ti = this.CreateCommandTabItem(this.hsTabCommands.Items.Count);
            this.hsTabCommands.Items.Add(ti);

            if (this.hsTabCommands.Items.Count == 8) {
                this.hsAddCommand.IsEnabled = false;
            }

            this.hsTabCommands.SelectedIndex = this.hsTabCommands.Items.Count - 1;
        }
        private void hsRemoveCommand_Click(object sender, RoutedEventArgs e) {            
            if (this._HotString == null) { return; }

            this.hsAddCommand.IsEnabled = true;

            if (hsTabCommands.Items.Count == 1) {
                this._HotString.Commands.Clear();
                this.InitializeHotString();
            }
            else if (hsTabCommands.SelectedIndex == 0) {
                this._HotString.Commands.RemoveAt(0);
                this.InitializeHotString();
            }
            else {
                int tabIndex = hsTabCommands.SelectedIndex;
                this._HotString.Commands.RemoveAt(tabIndex);
                this.hsTabCommands.Items.RemoveAt(tabIndex);

                if (this.hsTabCommands.Items.Count <= tabIndex) {
                    this.hsTabCommands.SelectedIndex = tabIndex - 1;
                }
                else {
                    this.hsTabCommands.SelectedIndex = tabIndex;
                    // Reorder tab headers
                    int count = 0;
                    foreach (TabItem ti in this.hsTabCommands.Items) {
                        ++count;
                        ti.Header = count.ToString();
                    }
                }
            }
        }

        private void InitializeHotString() {
            this._IsApply = false;

            this.hsTabCommands.SelectedIndex = 0;

            if (this._HotString == null) {
                this.hsCommand.Command = string.Empty;
                this.hsCommand.Arguments = string.Empty;
                this.hsHotString.Text = string.Empty;
                this.hsAudioInput.IsChecked = false;
            }
            else {
                this.hsHotString.Text = this._HotString.Name;
                if (this._HotString.Commands.Count > 0) {
                    this.hsCommand.Command = this._HotString.Commands[0].Command;
                    this.hsCommand.Arguments = this._HotString.Commands[0].Arguments;
                }
                else {
                    this.hsCommand.Command = string.Empty;
                    this.hsCommand.Arguments = string.Empty;
                }

                if (this._HotString.EnabledInputs.Contains("audio")) {
                    if (this._HotString.EnabledInputs.Contains("string")) {
                        this.hsAudioInput.IsChecked = null;
                    }
                    else {
                        this.hsAudioInput.IsChecked = true;
                    }
                }
                else {
                    this.hsAudioInput.IsChecked = false;
                }
            }

            this.InitializeTabCommands();

            this._IsApply = true;
        }
        private void InitializeTabCommands() {
            for (int i = this.hsTabCommands.Items.Count - 1; i >= 1; i--) {
                this.hsTabCommands.Items.RemoveAt(i);
            }

            if (this._HotString != null) {
                for (int i = 1; i < this._HotString.Commands.Count; i++) {
                    TabItem ti = this.CreateCommandTabItem(i, this._HotString.Commands[i]);
                    this.hsTabCommands.Items.Add(ti);
                }
            }
        }

        private TabItem CreateCommandTabItem(int index) {
            return this.CreateCommandTabItem(index, new CommandInfo());
        }
        private TabItem CreateCommandTabItem(int index, CommandInfo commandInfo) {
            TabItem ti = new TabItem();
            CommandSelector cs = new CommandSelector();

            ti.Header = (index + 1).ToString();
            cs.Command = commandInfo.Command;
            cs.Arguments = commandInfo.Arguments;
            cs.CommandChanged += new EventHandler(hsCommand_CommandChanged);
            
            ti.Content = cs;

            return ti;
        }

        #region ICommandConfigurator<ICommand> Members
        public void InitializeConfig(ICommand config) {
            if (config == null) {
                this._HotString = null;
            }
            else {
                this._HotString = config as HotString;
            }

            this.InitializeHotString();
        }

        public UserControl ConfigPanel { get { return this; } }

        public event CommandNameEventHandler CommandNameChanged;
        protected virtual void OnCommandNameChanged(object sender, CommandNameEventArgs e) {
            if (this.CommandNameChanged != null) {
                this.CommandNameChanged(sender, e);
            }
        }
        #endregion
    }
}
